package com.dure.hotmemory.server;

/**
 * Created by dure on 16-4-10.
 */

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.content.FileProvider;
import android.widget.RemoteViews;

import com.dure.hotmemory.BuildConfig;
import com.dure.hotmemory.R;
import com.socks.library.KLog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by ZhangLong on 2014/11/12.
 */
public class UpdateService extends Service {

    //文件存储
    private File updateDir = null;
    private File updateFile = null;

    //通知栏
    private NotificationManager updateNotificationManager = null;
    private Notification updateNotification = null;
    //通知栏跳转Intent
    private Intent updateIntent = null;
    private PendingIntent updatePendingIntent = null;


    //下载状态
    private final static int DOWNLOAD_COMPLETE = 0;
    private final static int DOWNLOAD_FAIL = 1;
    private final static int DOWNLOADING = 2;

    private String url;

    private int imgId;
    private String name;
    private int downloadIndex;
    private RemoteViews remoteViews;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            //获取传值
            url = intent.getStringExtra("url");
            imgId = intent.getIntExtra("img_id", 0);
            name = intent.getStringExtra("name");
            downloadIndex = intent.getIntExtra("download_index", 0);

        }

        //创建文件
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            updateDir = new File(Environment.getExternalStorageDirectory(), "app/download/");
            updateFile = new File(updateDir.getPath(), name + ".apk");
        }

        this.updateNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        //设置下载过程中，点击通知栏，回到主界面
        updateIntent = new Intent();
        updatePendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);
        //设置通知栏显示内容
        Notification.Builder builder = new Notification.Builder(this)
                .setAutoCancel(true)
                .setContentTitle(name)
                .setContentText("开始下载")
                .setContentIntent(updatePendingIntent)
                .setSmallIcon(imgId)
                .setWhen(System.currentTimeMillis())
                .setOngoing(true);
        updateNotification = builder.build();

        //通知自定义视图
//        updateNotification.contentView = new RemoteViews(getPackageName(), R.layout.download_layout);
//        updateNotification.contentView.setImageViewResource(R.id.app_iv, imgId);
//        updateNotification.contentView.setProgressBar(R.id.progress_bar, 100, 0, false);
        updateNotification.contentIntent = updatePendingIntent;//这个pengdingIntent很重要，必须要设置

        //发出通知
        updateNotificationManager.notify(downloadIndex, updateNotification);


        //开启一个新的线程下载，如果使用Service同步下载，会导致ANR问题，Service本身也会阻塞
        new Thread(new updateRunnable()).start();//这个是下载的重点，是下载的过程

        return super.onStartCommand(intent, flags, startId);
    }


    private Handler updateHandler = new Handler() {
        Notification.Builder builder;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWNLOAD_COMPLETE:
                    Intent installIntent = installAPK(updateFile);
                    startActivity(installIntent);
                    updatePendingIntent = PendingIntent.getActivity(UpdateService.this, 0, installIntent, 0);

                    builder = new Notification.Builder(UpdateService.this)
                            .setAutoCancel(true)
                            .setContentTitle(name)
                            .setContentText("下载完成,点击安装。")
                            .setContentIntent(updatePendingIntent)
                            .setSmallIcon(imgId)
                            .setWhen(System.currentTimeMillis())
                            .setDefaults(Notification.DEFAULT_SOUND);
                    updateNotification = builder.build();

                    updateNotificationManager.notify(downloadIndex, updateNotification);

                    //停止服务
//                    stopSelf();
                    break;
                case DOWNLOAD_FAIL:
                    //下载失败
                    builder = new Notification.Builder(UpdateService.this)
                            .setAutoCancel(true)
                            .setContentTitle(name)
                            .setContentText("下载失败")
                            .setContentIntent(updatePendingIntent)
                            .setSmallIcon(imgId)
                            .setWhen(System.currentTimeMillis())
                            .setDefaults(Notification.DEFAULT_SOUND);
                    updateNotification = builder.build();
                    updateNotificationManager.notify(downloadIndex, updateNotification);

//                    updateNotificationManager.cancel(downloadIndex);
                    break;
                case DOWNLOADING:
//                    updateNotification.contentView.setProgressBar(R.id.progress_bar, 100, msg.arg1, false);
//                    updateNotification.contentView.setTextViewText(R.id.title_tv, "下载中" + msg.arg1 + "%");
                    builder = new Notification.Builder(UpdateService.this)
                            .setAutoCancel(true)
                            .setContentTitle(name)
                            .setContentText("下载中" + msg.arg1 + "%")
                            .setContentIntent(updatePendingIntent)
                            .setSmallIcon(imgId)
                            .setProgress(100, msg.arg1,false)
                            .setWhen(System.currentTimeMillis())
                            .setOngoing(true);
                    updateNotification = builder.build();
                    updateNotificationManager.notify(downloadIndex, updateNotification);
                    break;
                default:
                    stopSelf();
            }
        }
    };

    class updateRunnable implements Runnable {
        Message message = updateHandler.obtainMessage();

        public void run() {

            try {
                //增加权限;
                if (!updateDir.exists()) {
                    updateDir.mkdirs();
                }
                if (!updateFile.exists()) {
                    updateFile.createNewFile();
                }
                //下载函数，以QQ为例子
                //增加权限;
                long downloadSize = downloadUpdateFile(url, updateFile);
                if (downloadSize > 0) {
                    message.what = DOWNLOAD_COMPLETE;
                    //下载成功
                    updateHandler.sendMessage(message);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                message.what = DOWNLOAD_FAIL;
                //下载失败
                updateHandler.sendMessage(message);
            }
        }
    }

    public long downloadUpdateFile(String downloadUrl, File saveFile) throws Exception {
        //这样的下载代码很多，我就不做过多的说明
        int downloadCount = 0;
        int currentSize = 0;
        long totalSize = 0;
        int updateTotalSize = 0;

        HttpURLConnection httpConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;

        try {
            URL url = new URL(downloadUrl);
            httpConnection = (HttpURLConnection) url.openConnection();
            httpConnection.setRequestProperty("User-Agent", "PacificHttpClient");
            if (currentSize > 0) {
                httpConnection.setRequestProperty("RANGE", "bytes=" + currentSize + "-");
            }
            httpConnection.setConnectTimeout(10000);
            httpConnection.setReadTimeout(20000);
            updateTotalSize = httpConnection.getContentLength();
            if (httpConnection.getResponseCode() == 404) {
                throw new Exception("fail!");
            }
            is = httpConnection.getInputStream();


            fos = new FileOutputStream(saveFile, false);
            byte buffer[] = new byte[4096];
            int readsize = 0;
            while ((readsize = is.read(buffer)) > 0) {
                fos.write(buffer, 0, readsize);
                totalSize += readsize;
                // 每增加百分之一更新一次
                if ((int) (totalSize * 100 / updateTotalSize) - downloadCount >= 1) {
                    downloadCount += 1;
                    Message msg = updateHandler.obtainMessage();
                    msg.what = DOWNLOADING;
//                    msg.arg1 = (int) (totalSize * 100 / updateTotalSize);
                    msg.arg1 = downloadCount;
                    updateHandler.sendMessage(msg);
                }

            }
        } finally {
            if (httpConnection != null) {
                httpConnection.disconnect();
            }
            if (is != null) {
                is.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
        return totalSize;
    }


    private Intent installAPK(File apkFile){

        Intent intent = new Intent(Intent.ACTION_VIEW);
        //判断是否是AndroidN以及更高的版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileProvider", apkFile);
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

        return intent;
    }
}